package com.yanqu.road.server.manger.kowloon.battle.role.hero;

import com.yanqu.road.entity.kowloon.battle.KowloonBattleHeroData;
import com.yanqu.road.entity.kowloon.common.KowloonRange;
import com.yanqu.road.entity.kowloon.enums.battle.eKowloonHeroState;
import com.yanqu.road.server.manger.kowloon.battle.KowloonBattleFunc;
import com.yanqu.road.server.manger.kowloon.battle.KowloonGame;
import com.yanqu.road.server.manger.kowloon.battle.role.KowloonRole;
import com.yanqu.road.entity.kowloon.common.Rect;
import com.yanqu.road.server.manger.kowloon.battle.role.enemy.KowloonEnemy;

import java.util.ArrayList;
import java.util.List;

public abstract class KowloonHero extends KowloonRole {

    public KowloonBattleHeroData data;

    public eKowloonHeroState state;

    public Rect attackRect;

    /**
     * 攻击速度 每秒攻击次数x1000
     */
    public double cdTime;

    public List<KowloonEnemy> targetEnemys = new ArrayList<>();

    public KowloonHero(KowloonGame game) {
        super(game);
    }

    public static KowloonHero createHero(KowloonGame game, KowloonBattleHeroData data) {
        KowloonHero hero = null;
        switch (data.getHeroId()) {
            case 1001:
                hero = new KowloonHero1(game);
                break;
            case 1002:
                hero = new KowloonHero2(game);
                break;
            case 1003:
                hero = new KowloonHero3(game);
                break;
            case 1004:
                hero = new KowloonHero4(game);
                break;
            case 1005:
                hero = new KowloonHero5(game);
                break;
            case 1006:
                hero = new KowloonHero6(game);
                break;
            case 1007:
                hero = new KowloonHero7(game);
                break;
            default:
                break;
        }
        if (hero != null) {
            hero.initData(data);
        }
        return hero;
    }

    private void initData(KowloonBattleHeroData data) {
        this.data = data;
        this.state = eKowloonHeroState.Idle;
        this.cdTime = Math.floor(1000000.0 / data.getProperty().getAtkSpeed());
        this.pos = game.getPos(this.data.getPos().getCol() + 1, this.data.getPos().getRow() + 1);
        if (this.data.getHeroId() == 1003) { // 管家婆的攻击范围按武器半径算
            int weaponRadius = this.data.getProperty().getWeaponRadius();
            this.attackRect = new Rect(this.pos.getX() - weaponRadius, this.pos.getY() - weaponRadius, weaponRadius * 2,
                    weaponRadius * 2);
        } else {
            KowloonRange attackRange = this.data.getProperty().getAttackRange();
            this.attackRect = new Rect(this.pos.getX() - attackRange.getWidth() / 2.0,
                    this.pos.getY() - attackRange.getHeight() / 2.0, attackRange.getWidth(), attackRange.getHeight());
        }
    }

    @Override
    public void updateAI(double dt) {
        super.updateAI(dt);
        switch (this.state) {
            case Idle:
                List<KowloonEnemy> enemys = this.findEnemys();
                if (enemys.size() > 0) {
                    this.targetEnemys = enemys;
                    this.stateChange(eKowloonHeroState.Attack);
                }
                break;
            case Attack:
                this.attack();
                break;
            case Cd:
                if (game.gameTime >= this.cdNextTime) {
                    this.stateChange(eKowloonHeroState.Idle);
                }
                break;
            case Attack2:
                this.attack2();
                break;
        }
    }

    public abstract void attack();

    public double cdNextTime;

    public void cd() {
        this.cdNextTime = game.getGameTime() + this.cdTime;
        this.stateChange(eKowloonHeroState.Cd);
    }

    public void attack2() {
        this.stateChange(eKowloonHeroState.Idle);
    }

    public void stateChange(eKowloonHeroState state) {
        this.state = state;
        this.updateAI(0);
    }

    /**
     * 找敌人
     */
    private List<KowloonEnemy> findEnemys() {
        List<KowloonEnemy> enemys = new ArrayList<>();
        for (KowloonEnemy enemy : game.getEnemys()) {
            if (enemy.isAlive()) {
                if (KowloonBattleFunc.rectRect(enemy.getHurtRect(), this.attackRect)) {
                    enemys.add(enemy);
                }
            }
        }
        /** 策划说优先找上面的怪 ,其次找近的 */
        enemys.sort((o1, o2) -> {
            double y1 = o1.pos.getY() - this.pos.getY();
            if (y1 < 0) {
                y1 = -y1 - 30000;
            }
            double y2 = o2.pos.getY() - this.pos.getY();
            if (y2 < 0) {
                y2 = -y2 - 30000;
            }
            return Double.compare(y1, y2);
        });
        return enemys;
    }

    public KowloonBattleHeroData getData() {
        return data;
    }

    public void setData(KowloonBattleHeroData data) {
        this.data = data;
    }

    public eKowloonHeroState getState() {
        return state;
    }

    public void setState(eKowloonHeroState state) {
        this.state = state;
    }

    public Rect getAttackRect() {
        return attackRect;
    }

    public void setAttackRect(Rect attackRect) {
        this.attackRect = attackRect;
    }

    public double getCdTime() {
        return cdTime;
    }

    public void setCdTime(int cdTime) {
        this.cdTime = cdTime;
    }
}
